<?php
/**
 * PythonApi 接入
 * @App	
 * @Group 
 * @Action PythonApiService
 * @author lilei
 * @date 2018年7月14日
 *
 */
namespace app\common\service;
use app\common\library\CommonFun;
use app\common\model\coin\CoinRuntimeModel;

class PythonApiService {
	/**
	 * Memcache配置名称
	 * @var string
	 */
	protected static $memcache = 'default';
	
	/**
	 * Memcache缓存key前缀
	 * @var string
	 */
	protected static $memcache_key_prefix = 'MemcachePythonApiServicePrefix';
	
	/**
	 * Curl链接句柄
	 * @var object
	 */
	static $curlHandel;
	
	/**
	 * Curl 链接超时时间(s)
	 * @var integer
	 */
	static $curlConnectTimeOut = 10;
	
	/**
	 * Curl 超时时间(s)
	 * @var integer
	 */
	static $curlTimeOut = 10;
	
	/**
	 * Api接口地址
	 * @var string
	 */
	static $apiUrl;
	
	/**
	 * Api返回数据
	 * @var array
	 */
	static $apiData;
	
	/**
	 * 要解析的PyAPI返回数据的字段
	 * @var string
	 */
	static $parsePyApiField = null;
	
	/**
	 * 构造函数
	 */
	public function __construct() {
		// 获取配置文件
		CommonFun::get_other_config("PythonApiConfig",2);
		// 创建Curl链接句柄
		self::createCurl();
	}
	
	/**
	 * 返回单例模型
	 * @return static
	 */
	public static function getInstance() {
		$param = func_get_args ();
		return get_instance_of ( get_called_class (), '', $param );
	}
	
	/**
	 * 创建Curl 链接句柄
	 * @return Curl
	 */
	private static function createCurl() {
		import("ORG.Net.Curl");
		self::$curlHandel = new Curl();
		self::$curlHandel->connecttimeout = self::$curlConnectTimeOut;
		self::$curlHandel->timeout = self::$curlTimeOut;
	}
	
	/**
	 * 获取Api原始数据
	 * @param array $request_param 请求数据
	 * @param string $method		请求方法
	 * @return array
	 */
	protected static function getPyApiData(array $request_param=array(), $method="GET") {
		if ( !self::$apiUrl ) {
			return array();
		}
		// 获取数据
		$res = self::$curlHandel->http(self::$apiUrl, $method, $request_param);
		$res = json_decode($res, true);
		// 赋值属性
		self::$apiData = $res ?: array();
		// 解析数据
		return $parseData = self::parsePyApiData();
	}
	
	/**
	 * 解析Api原始数据
	 */
	protected static function parsePyApiData() {
		$data = self::$apiData;
		if ( !$data ) {
			return array();
		}
		$field = "data";
		if ( self::$parsePyApiField ) {
			$return = (isset( $data[$field][self::$parsePyApiField] ) && $data[$field][self::$parsePyApiField] ) ? $data[$field][self::$parsePyApiField] : array() ;
			self::$parsePyApiField = null;
			return $return;
		}else {
			return (isset( $data[$field] ) && $data[$field] ) ? $data[$field] : array() ; 
		}
		
	}
	
	/**
	 * 获取缓存数据
	 * @param string $key_mark 缓存key标识
	 * @return bool
	 */
	public static function getMemcacheData( $key_mark ) {
		// 缓存key
		$cache_key = self::getMemcacheKey($key_mark);
		// Memcache缓存对象
		$cache_obj = CommonFun::get_memcache(static::$memcache);
		// 从缓存获取
		$data = $cache_obj->get($cache_key);
		return $data ?: false;
	}
	
	/**
	 * 设置缓存数据
	 * @param string $key_mark 缓存key标识
	 * @param mixed $data 缓存数据
	 * @param int $expire 过期时间
	 * @return bool
	 */
	public static function setMemcacheData( $key_mark, $data, $expire=300 ) {
		if ( !$key_mark || !$data ) {
			return false;
		}
		// 缓存key
		$cache_key = self::getMemcacheKey($key_mark);
		// Memcache缓存对象
		$cache_obj = CommonFun::get_memcache(static::$memcache);
		// 缓存数据
		$cache_res = $cache_obj->set($cache_key, $data, $expire);
		
		return true;
	}
	
	/**
	 * 生成Memcache缓存的key
	 * @return string
	 */
	protected static function getMemcacheKey($key_mark) {
		$key_mark = trim($key_mark);
		$key = self::$memcache_key_prefix.'_'.get_called_class().'_'.$key_mark;
		return md5($key);
	}
	
	/**
	 * 获取交易所列表
	 * @return array
	 */
	public function getExchangeList() {
		self::$apiUrl = C("py_exchange_list");
		$res = self::getPyApiData();
		return $res;
	}
	
	/**********************************************************************行情排行数据列表******************************************************************/
	
	/**
	 * 刷新榜单数据
	 */
	public function refreshBillBoardCache() {
		$allMethod = CommonFun::get_class_all_methods(__CLASS__);
		foreach ( $allMethod as $_method ) {
			$_type = $_method['type'];
			if ( $_type!="public" ) {
				continue;
			}
			$doc = $_method['doc'];
			if ( strpos($doc, "@needBillBoardRefresh") !==false ) {
				$function = $_method['name'];
				$callback = array( &$this, $function );
				$param_arr = array(false);
				call_user_func_array($callback, $param_arr);
			}
		}
	}
	
	/**
	 * 24H成交额TOP500
	 * @needBillBoardRefresh
	 */
	public function getTopVolume( $from_cache=true ) {
		self::$apiUrl = C("py_top_volume");
		// 缓存key
		$key_mark = self::$apiUrl;
		// 数据信息
		$data = false;
		// 从缓存获取
		$from_cache && $data = self::getMemcacheData($key_mark);
		// 没有获取到缓存或者from_cache为假
		if ( $data===false ) {
			$data = self::getPyApiData();
			if ( $data ) {
				self::setMemcacheData($key_mark, $data);
			}
		}
		
		return $data;
	}
	
	/**
	 * 流通市值榜
	 * @needBillBoardRefresh
	 */
	public function getTopMarketcap( $from_cache=true ) {
		self::$apiUrl = C("py_top_marketcap");
		// 缓存key
		$key_mark = self::$apiUrl;
		// 数据信息
		$data = false;
		// 从缓存获取
		$from_cache && $data = self::getMemcacheData($key_mark);
		// 没有获取到缓存或者from_cache为假
		if ( $data===false ) {
			$data = self::getPyApiData();
			if ( $data ) {
				self::setMemcacheData($key_mark, $data);
			}
		}
		
		return $data;
	}
	
	/**
	 * 24小时涨幅榜
	 * @needBillBoardRefresh
	 */
	public function get24hRise( $from_cache=true ) {
		self::$apiUrl = C("py_24h_raise");
		// 缓存key
		$key_mark = self::$apiUrl;
		// 数据信息
		$data = false;
		// 从缓存获取
		$from_cache && $data = self::getMemcacheData($key_mark);
		// 没有获取到缓存或者from_cache为假
		if ( $data===false ) {
			$data = self::getPyApiData();
			if ( $data ) {
				self::setMemcacheData($key_mark, $data);
			}
		}
		
		return $data;
	}
	
	/**
	 * 24小时跌幅榜
	 * @needBillBoardRefresh
	 */
	public function get24hFall( $from_cache=true ) {
		self::$apiUrl = C("py_24h_fall");
		// 缓存key
		$key_mark = self::$apiUrl;
		// 数据信息
		$data = false;
		// 从缓存获取
		$from_cache && $data = self::getMemcacheData($key_mark);
		// 没有获取到缓存或者from_cache为假
		if ( $data===false ) {
			$data = self::getPyApiData();
			if ( $data ) {
				self::setMemcacheData($key_mark, $data);
			}
		}
		
		return $data;
	}
	
	/**********************************************************************折线数据******************************************************************/
	
	/**
	 * 获取交易所Token折线数据
	 * @param string 	$exchange 交易所
	 * @param int 		$coin_id	币种编号
	 * @param number $day_num	请求天数 1, 7, 14, 30, 90, 180, 365
	 * @param bool $from_cache 是否从缓存获取
	 */
	public function getExchangeChartsDataList($exchange, $coin_id, $day_num=1, $from_cache=true ) {
		$apiUrl = C("py_charts");
		self::$apiUrl = $apiUrl."$exchange/$coin_id/{$day_num}/";
		// 缓存key
		$key_mark = self::$apiUrl;
		// 数据信息
		$data = false;
		// 从缓存获取
		$from_cache && $data = self::getMemcacheData($key_mark);
		// 没有获取到缓存或者from_cache为假
		if ( $data===false ) {
			self::$parsePyApiField = $exchange;
			$data = self::getPyApiData();
			if ( $data ) {
				self::setMemcacheData($key_mark, $data);
			}
		}
		
		return $data;
	}
	
	/**********************************************************************币种行情分析日报数据******************************************************************/
	
	/**
	 * 币种行情分析日报数据
	 */
	public function getTradeDaily( $coin_id_set ) {
		self::$apiUrl = C("py_trade_daily");
		if ( is_array($coin_id_set) ) {
			$coin_id_set = implode(",", $coin_id_set);
		}
		$request_param =[
				"coin_id" =>$coin_id_set
		];
		$data = self::getPyApiData( $request_param );
		return $data;
	}
	
	/**********************************************************************Ticker数据******************************************************************/
	
	/**
	 * 批量获取Ticker交易对数据
	 * @param string $exchange	交易所名称
	 * @param array $base_quote_list 交易对数据列表
	 * 格式array( {eth的ID}=>array('usd的ID','cny的ID'), {btc的ID}=>array('usd的ID') ),
	 * @return array
	 */
	public function mutiGetTickerList( $exchange, array $base_quote_list ) {
		if ( !$exchange || !$base_quote_list ) {
			return array();
		}
		// 静态化返回结果
		static $res_list=array();
		// 请求参数数组
		$request_param = array();
		// 构建请求数组
		foreach ( $base_quote_list as $base=>$quote_arr ) {
			if ( !$quote_arr ) {
				continue;
			}
			foreach ( $quote_arr as $quote ) {
				$request_param[] = $base."-".$quote;
			}
		}
		
		// 返回结果集
		$return = array();
		if ( !$request_param ) {
			return $return;
		}
		
		// 设置静态标识和缓存Key
		$static_key = $key_mark = md5( $exchange.CommonFun::json_encode2($request_param));
		if ( isset( $res_list[$static_key] ) ) {
			return $res_list[$static_key];
		}
		
		// 获取数据
		self::$apiUrl = C("py_muti_ticker_pair");
		// 构建接口参数
		$param = array(
				"symbol" => implode(",", $request_param),
				"exchange" => $exchange
		);
		self::$parsePyApiField = $exchange;
		$return = self::getPyApiData($param);
		if ( $return ) {
			// 有返回数据, 存入缓存
			self::setMemcacheData($key_mark, $return);
		}else {
			// 无返回数据, 从缓存获取
			$res = self::getMemcacheData($key_mark);
			$return = $res ?: array();
		}
		
		// 放入静态变量
		$res_list[$static_key] = $return;
		
		return $return;
	}
	
	/**********************************************************************用户数据******************************************************************/

    /**
     * 获取一篇内容对应的相关标签及币种
     * @param $content
     */
    public  function get_content_tags( $content )
    {
        $apiUrl = C("py_spider_tag_list");
        $param = array(
            'content' => $content
        );

        self::$apiUrl = $apiUrl;
        // 获取数据
        $data = self::getPyApiData( $param, 'POST');

        // 返回数据
        return $data?:array();
    }

    public function get_content_participle( $content )
    {
        $apiUrl = C("py_tag_segments");
        $param = array(
            'content' => $content
        );

        self::$apiUrl = $apiUrl;
        // 获取数据
        $data = self::getPyApiData( $param, 'POST');

        // 返回数据
        return $data?:array();
    }


	/**
	 * 获取用户持仓币种编号列表
	 * @param int $user_id 用户编号
	 * @return array
	 */
	public function getUserAssetCoinID ( $user_id ) {
		// 接口
		$apiUrl = C("py_user_asset_coin_list");
		self::$apiUrl = $apiUrl.$user_id;
		// 获取数据
		$data = self::getPyApiData();
		// 返回数据
		return $data?:array();
	}

	/**
	 * 获取标签列表 
	 * @param  array  $param [参数]
	 * @return [type]        [description]
	 */
	public function  get_tag_list($param=[])
    {
       	self::$apiUrl = C("py_tag_nodes");	
       	// 获取数据
		$data = self::getPyApiData($param);
		// 返回数据
		return $data ?: array();
    }
    /**
     * 获取标签关系列表/添加标签关系
     * @param  array  $param  [参数]
     * @param  string $method [方法]
     * @return [type]         [description]
     */
    public function get_tag_relation($param=[], $method='GET')
    {
    	self::$apiUrl = C("py_tag_relation");	
    	// 获取数据
		$data = self::getPyApiData($param, $method);
		// 返回数据
		return $data ?: array();
    }
    /**
     * 标签关系列表
     * @param  array  $param  [description]
     * @param  string $method [description]
     * @return [type]         [description]
     */
    public function  get_search_list($param=[], $method='GET')
    {
       	self::$apiUrl = C("py_search_tag");	
       	// 获取数据
		$data = self::getPyApiData($param, $method);
		// 返回数据
		return $data ?: array();
    }

    /**
     *  添加标签
     * @param array  $param  [description]
     * @param string $method [description]
     */
    public  function  add_tag_list($param=[], $method='GET')
	{
		self::$apiUrl = C("py_tag_node");	
       	// 获取数据
		$data = self::getPyApiData($param, $method);
		// 返回数据
		return $data ?: array();
	}

	// 获取用户持仓数据
    public function  user_coin_all( $limit = 100000)
    {
        self::$apiUrl = C("py_user_coin");
        // 获取数据
        $data = self::getPyApiData(  array( 'limit' => $limit ) );
        $data_format = array();
        // 获取币种简称列表

        $coin_model = CoinRuntimeModel::getInstance();
        $coin_list = $coin_model->get_key_value( 'id', 'symbol');

        foreach ( $data as $key => $value ){
            $data_format[$key] = array(
                'exchange' => array(),
                'manual'   => array(),
                'chain'    => array()
            );
            foreach ( $value['exchange'] as $v ){
                foreach ( $v as $k => $vo ){
                    if ( !isset( $coin_list[$k] ) ){
                        continue;
                    }

                    $data_format[$key]['exchange'][] = $coin_list[$k];
                }
            }

            foreach ( $value['manual'] as $k => $v ){
                if ( !isset( $coin_list[$k] ) ){
                    continue;
                }

                $data_format[$key]['manual'][] = $coin_list[$k];
            }

            foreach ( $value['chain'] as $v ){
                foreach ( $v as $k => $vo ){
                    if ( !isset( $coin_list[$k] ) ){
                        continue;
                    }
                    $data_format[$key]['chain'][] = $coin_list[$k];
                }
            }
        }

        // 返回数据
        return $data_format ?: array();
    }
    /**
     * 获取币种监测
     * @param  [type] $param [description]
     * @return [type]        [description]
     */
    public function coinDraft($param)
    {
    	self::$apiUrl = C("py_coin_draft");	
       	// 获取数据
		$data = self::getPyApiData($param);
		// 返回数据
		return $data ?: array();
    }
    
    /**
     * 获取映射列表
     * @return [type] [description]
     */
    public function getMappingList($param=[])
    {
    	self::$apiUrl = C("py_mapping_list");	
       	// 获取数据
		$data = self::getPyApiData($param);
		// 返回数据
		return $data ?: array();
    }
	
}